package com.ssy.lingxi.system.service.impl;

import com.ssy.lingxi.common.constant.CommonConstant;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.model.vo.paas.BaseLevelConfigSetRightsVO;
import com.ssy.lingxi.system.dao.MemberEquitiesRepository;
import com.ssy.lingxi.system.dao.MemberGradeRepository;
import com.ssy.lingxi.system.dao.RoleRepository;
import com.ssy.lingxi.system.dto.request.*;
import com.ssy.lingxi.system.dto.response.MemberEquitiesSetDetailsResponse;
import com.ssy.lingxi.system.dto.response.MemberGradeDetailsResponse;
import com.ssy.lingxi.system.dto.response.MemberGradeListResponse;
import com.ssy.lingxi.system.dto.response.MiddlegroundUserLoginResponse;
import com.ssy.lingxi.system.entity.MemberEquities;
import com.ssy.lingxi.system.entity.MemberGrade;
import com.ssy.lingxi.system.entity.Role;
import com.ssy.lingxi.system.service.MemberGradeService;
import com.ssy.lingxi.system.utils.UserDetailsUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class MemberGradeServiceImpl implements MemberGradeService {

    @Resource
    MemberGradeRepository memberGradeRepository;

    @Resource
    UserDetailsUtil userDetailsUtil;

    @Resource
    MemberEquitiesRepository memberEquitiesRepository;

    @Resource
    RoleRepository roleRepository;

    /**
     * 查询会员等级与权益设置列表
     *
     * @param request
     * @author wrc
     * @date 2020/6/5
     */
    @Override
    public Wrapper<PageData<MemberGradeListResponse>> memberGradeList(MemberGradeListRequest request) {
        Specification<MemberGrade> specification = (Specification<MemberGrade>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if(StringUtils.hasLength(request.getMemberName())) {
                Join<Object, Object> roleJoin = root.join("role", JoinType.LEFT);
                list.add(criteriaBuilder.like(roleJoin.get("name").as(String.class), "%" + request.getMemberName().trim() + "%"));
            }

            if(request.getMemberGradeType() != null && !request.getMemberGradeType().equals(0)) {
                list.add(criteriaBuilder.equal(root.get("memberGradeType").as(Integer.class), request.getMemberGradeType()));
            }

            if(StringUtils.hasLength(request.getMemberGradeLabel())) {
                list.add(criteriaBuilder.like(root.get("memberGradeLabel").as(String.class), "%" + request.getMemberGradeLabel().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Pageable pageable = PageRequest.of(request.getCurrent(), request.getPageSize(), Sort.by("id").descending());
        Page<MemberGrade> pageList = memberGradeRepository.findAll(specification, pageable);
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(memberGrade -> {
            MemberGradeListResponse response = new MemberGradeListResponse();
            response.setId(memberGrade.getId());
            response.setMemberGrade(memberGrade.getMemberGrade());
            response.setMemberGradeLabel(memberGrade.getMemberGradeLabel());
            response.setMemberGradeType(memberGrade.getMemberGradeType());
            response.setScoreLabel(memberGrade.getScoreLabel());
            response.setGradeExplain(memberGrade.getGradeExplain());
            response.setRoleName(memberGrade.getRole().getName());
            response.setRoleType(memberGrade.getRole().getRoleType());
            response.setMemberType(memberGrade.getRole().getMemberType());
            response.setState(memberGrade.getState());
            return response;
        }).collect(Collectors.toList())));
    }

    /**
     * 会员权益设置
     *
     * @param request
     * @author wrc
     * @date 2020/6/5
     */
    @Transactional
    @Override
    public Wrapper memberEquitiesSet(MemberEquitiesSetRequest request) {
        MemberGrade memberGrade = memberGradeRepository.findById(request.getId()).orElse(null);
        if(memberGrade == null) {
            return Wrapper.fail("等级配置不存在");
        }

        //会员服务
        BaseLevelConfigSetRightsVO rightsVO = new BaseLevelConfigSetRightsVO();
        rightsVO.setLevel(memberGrade.getMemberGrade());
        rightsVO.setRoleId(memberGrade.getRole().getId());
        rightsVO.setMemberLevelTypeEnum(memberGrade.getMemberGradeType());
        rightsVO.setRightTypeEnums(new ArrayList<>());

        if(CollectionUtils.isEmpty(request.getMemberEquitieIds())) {
            memberGrade.setMemberEquitiesSet(new HashSet<>());
        } else {
            List<MemberEquities> memberEquitiesList = memberEquitiesRepository.findAllById(request.getMemberEquitieIds());
            if(memberEquitiesList.size() != request.getMemberEquitieIds().size()) {
                return Wrapper.fail("权益不存在");
            }

            rightsVO.setRightTypeEnums(memberEquitiesList.stream().map(MemberEquities::getTypeEnum).collect(Collectors.toList()));

            memberGrade.setMemberEquitiesSet(new HashSet<>(memberEquitiesList));
        }

        memberGradeRepository.saveAndFlush(memberGrade);
        return Wrapper.success();
    }

    /**
     * 会员等级设置（为了兼容修改配置功能，所以先删后增）
     * @param request
     * @author wrc
     * @date 2020/6/5
     */
    @Transactional
    @Override
    public Wrapper memberGradeAdd(HttpServletRequest httpServletRequest,MemberGradeAddRequest request) {
        MiddlegroundUserLoginResponse loginUserDetails = userDetailsUtil.getLoginUserDetails(httpServletRequest);

        //判断前端传入的角色Id是否都存在
        List<Role> roleList = roleRepository.findAllById(request.getRoleIds());
        if(roleList.size() != request.getRoleIds().size()) {
            return Wrapper.fail("角色不存在");
        }

        MemberGrade existMemberGrade = memberGradeRepository.findFirstByMemberGrade(request.getMemberGrade());
        if(existMemberGrade != null && !existMemberGrade.getMemberGradeLabel().equals(request.getMemberGradeLabel())) {
            return Wrapper.fail("等级" + request.getMemberGrade() + "已经存在名称为'" + existMemberGrade.getMemberGradeLabel() + "'的等级标签，请勿配置等级相同名称不同的会员等级");
        }

        //去掉 “平台” 角色
        List<Role> roles = roleList.stream().filter(role -> !"平台".equals(role.getName())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(roles)) {
            return Wrapper.success();
        }

        List<MemberGrade> memberGradeList = memberGradeRepository.findByMemberGradeAndMemberGradeType(request.getMemberGrade(), request.getMemberType());

        List<MemberGrade> upsertList = new ArrayList<>();
        for (Role role : roles) {
            MemberGrade grade = memberGradeList.stream().filter(g -> g.getRole().getId().equals(role.getId())).findFirst().orElse(null);
            if(grade == null) {
                grade = new MemberGrade();
                grade.setCreateTime(System.currentTimeMillis());
                grade.setUpdateTime(System.currentTimeMillis());
                grade.setMemberEquitiesSet(new HashSet<>());
                grade.setRole(role);
                grade.setMemberGrade(request.getMemberGrade());
                grade.setMemberGradeLabel(request.getMemberGradeLabel());
                grade.setGradeExplain(request.getGradeExplain());
                grade.setMemberGradeType(request.getMemberType());
                grade.setCreateRoleId(loginUserDetails.getId());
                grade.setScoreLabel(request.getScoreLabel());
                grade.setState(1);
            } else {
                grade.setUpdateTime(System.currentTimeMillis());
                grade.setMemberGradeLabel(request.getMemberGradeLabel());
                grade.setGradeExplain(request.getGradeExplain());
                grade.setScoreLabel(request.getScoreLabel());
            }

            upsertList.add(grade);
        }

        memberGradeRepository.saveAll(upsertList);

        return Wrapper.success();
    }

    /**
     * 查询会员等级详情
     *
     * @param request
     * @author wrc
     * @date 2020/6/5
     */
    @Override
    public Wrapper<MemberGradeDetailsResponse> memberGradeDetails(MemberGradeDetailsRequest request) {
        //查询会员等级详情
        MemberGrade memberGrade = memberGradeRepository.findById(request.getId()).orElse(null);
        if(memberGrade == null){
            return  Wrapper.fail("会员等级信息不存在");
        }

        MemberGradeDetailsResponse memberGradeDetailsResponse=new MemberGradeDetailsResponse();
        memberGradeDetailsResponse.setId(memberGrade.getId());
        memberGradeDetailsResponse.setMemberGrade(memberGrade.getMemberGrade());
        memberGradeDetailsResponse.setMemberGradeLabel(memberGrade.getMemberGradeLabel());
        memberGradeDetailsResponse.setMemberType(memberGrade.getMemberGradeType());
        memberGradeDetailsResponse.setScoreLabel(memberGrade.getScoreLabel());
        memberGradeDetailsResponse.setGradeExplain(memberGrade.getGradeExplain());

        List<MemberGrade> memberGradeList = memberGradeRepository.findByMemberGradeAndMemberGradeType(memberGrade.getMemberGrade(), memberGrade.getMemberGradeType());
        memberGradeDetailsResponse.setRoles(memberGradeList.stream().map(MemberGrade::getRole).collect(Collectors.toList()));

        return Wrapper.success(memberGradeDetailsResponse);
    }

    /**
     * 修改会员等级
     * @param request
     * @author wrc
     * @date 2020/6/5
     */
    @Transactional
    @Override
    public Wrapper memberGradeUpdate(MemberGradeUpdateRequest request) {
        //去重
        List<Long> roleIds = request.getRoleIds().stream().distinct().collect(Collectors.toList());

        //判断前端传入的角色Id是否都存在
        List<Role> roleList = roleRepository.findAll();
        if(roleIds.stream().allMatch(roleId -> roleList.stream().allMatch(role -> role.getId().equals(roleId)))) {
            return Wrapper.fail("角色不存在");
        }

        //删除去掉的角色数据（根据会员等级类型、等级为Key作为判断条件）
        Specification<MemberGrade> specification = (Specification<MemberGrade>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberGradeType").as(Integer.class), request.getMemberType()));
            list.add(criteriaBuilder.equal(root.get("memberGrade").as(Integer.class), request.getMemberGrade()));
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };
        List<MemberGrade> allList = memberGradeRepository.findAll();
        List<MemberGrade> deleteList = allList.stream().filter(m -> !roleIds.contains(m.getRole().getId())).collect(Collectors.toList());
        memberGradeRepository.deleteAll(deleteList);

        //已经存在的角色
        //对已经存在的角色，修改等级、等级标签、等级类型
        List<MemberGrade> existList = allList.stream().filter(m -> roleIds.contains(m.getRole().getId())).collect(Collectors.toList());
        existList.forEach(memberGrade -> {
            memberGrade.setMemberGrade(request.getMemberGrade());
            memberGrade.setMemberGradeLabel(request.getMemberGradeLabel());
            memberGrade.setMemberGradeType(request.getMemberType());
            memberGrade.setScoreLabel(request.getScoreLabel());
            memberGrade.setGradeExplain(StringUtils.isEmpty(request.getGradeExplain()) ? "" : request.getGradeExplain().trim());
            memberGrade.setUpdateTime(System.currentTimeMillis());
        });
        memberGradeRepository.saveAll(existList);

        //要新增的角色
        List<Long> newRoleIds = roleIds.stream().filter(id -> existList.stream().noneMatch(e -> e.getRole().getId().equals(id))).collect(Collectors.toList());
        List<Role> roles = roleList.stream().filter(role -> newRoleIds.contains(role.getId())).collect(Collectors.toList());
        List<MemberGrade> memberGradeList = roles.stream().map(role -> {
            MemberGrade memberGrade = new MemberGrade();
            memberGrade.setMemberGrade(request.getMemberGrade());
            memberGrade.setMemberGradeLabel(request.getMemberGradeLabel());
            memberGrade.setMemberGradeType(request.getMemberType());
            memberGrade.setScoreLabel(request.getScoreLabel());
            memberGrade.setGradeExplain(StringUtils.isEmpty(request.getGradeExplain()) ? "" : request.getGradeExplain().trim());
            memberGrade.setCreateTime(System.currentTimeMillis());
            memberGrade.setRole(role);
            memberGrade.setMemberEquitiesSet(new HashSet<>());
            return memberGrade;
        }).collect(Collectors.toList());

        memberGradeRepository.saveAll(memberGradeList);
        return Wrapper.success();
    }

    /**
     * 删除会员等级
     * @param request
     * @author wrc
     * @date 2020/6/5
     */
    @Transactional
    @Override
    public Wrapper memberGradeDelete(MemberGradeDeleteRequest request) {
        Optional<MemberGrade> byId = memberGradeRepository.findById(request.getId());
        if(!byId.isPresent()){
            return  Wrapper.fail("会员等级信息不存在");
        }
        MemberGrade memberGrade = byId.get();
        if(CommonConstant.State.STATE_START.equals(memberGrade.getState())){
            return  Wrapper.fail("会员等级状态可用中无法删除");
        }

        memberGradeRepository.deleteById(request.getId());
        return Wrapper.success();
    }

    /**
     * 停用会员等级设置
     * @param request
     * @author wrc
     * @date 2020/6/5
     */
    @Transactional
    @Override
    public Wrapper memberGradeStop(MemberGradeDeleteRequest request) {
        MemberGrade memberGrade = memberGradeRepository.findById(request.getId()).orElse(null);
        if(memberGrade == null){
            return  Wrapper.fail("会员等级信息不存在");
        }

        memberGrade.setUpdateTime(System.currentTimeMillis());
        memberGrade.setState(request.getState());
        memberGradeRepository.save(memberGrade);
        return Wrapper.success();
    }

    /**
     * 查询权益详情
     *
     * @param request
     * @author wrc
     * @date 2020/8/4
     */
    @Override
    public Wrapper<List<MemberEquitiesSetDetailsResponse>> memberEquitiesSetDetails(MemberGradeDetailsRequest request) {
        MemberGrade memberGrade = memberGradeRepository.findById(request.getId()).orElse(null);
        if(memberGrade == null) {
            return Wrapper.fail("等级配置不存在");
        }

        //防止Null值
        List<MemberEquities> equitiesList = CollectionUtils.isEmpty(memberGrade.getMemberEquitiesSet()) ? new ArrayList<>() : new ArrayList<>(memberGrade.getMemberEquitiesSet());

        //查询全部权益
        List<MemberEquities> memberEquities = memberEquitiesRepository.queryByStateEquals(CommonConstant.State.STATE_START);
        List<MemberEquitiesSetDetailsResponse> list = memberEquities.stream().map(m -> {
            MemberEquitiesSetDetailsResponse response = new MemberEquitiesSetDetailsResponse();
            response.setId(m.getId());
            response.setName(m.getEquitiesName());
            response.setIsPitchOn(equitiesList.stream().anyMatch(e -> e.getId().equals(m.getId())) ? CommonConstant.State.STATE_START : CommonConstant.State.STATE_STOP);
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(list);
    }
}
